TypeScriptλ₯Ό μ¬μ©νμ¬ Express.js μ ν리μΌμ΄μ μ νμ μμ μ±μ κ°ννμΈμ. μ΄ κ°μ΄λλ λΌμ°νΈ νΈλ€λ¬ μ μ, λ―Έλ€μ¨μ΄ νμ΄ν, νμ₯ κ°λ₯νκ³ μ μ§ κ΄λ¦¬ κ°λ₯ν API ꡬμΆμ μν λͺ¨λ² μ¬λ‘λ₯Ό λ€λ£Ήλλ€.
TypeScript Express ν΅ν©: λΌμ°νΈ νΈλ€λ¬ νμ μμ μ±
TypeScriptλ νλ JavaScript κ°λ°μ μ΄μμ΄ λμ΄ μ½λ νμ§, μ μ§ κ΄λ¦¬μ± λ° νμ₯μ±μ ν₯μμν€λ μ μ νμ΄ν κΈ°λ₯μ μ 곡ν©λλ€. λ리 μ¬μ©λλ Node.js μΉ μ ν리μΌμ΄μ νλ μμν¬μΈ Express.jsμ ν¨κ» μ¬μ©νλ©΄ TypeScriptλ λ°±μλ APIμ κ²¬κ³ μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€. μ΄ ν¬κ΄μ μΈ κ°μ΄λμμλ TypeScriptλ₯Ό νμ©νμ¬ Express.js μ ν리μΌμ΄μ μμ λΌμ°νΈ νΈλ€λ¬ νμ μμ μ±μ ν보νλ λ°©λ²μ μ΄ν΄λ³΄κ³ , μ μΈκ³ μ¬μ©μλ₯Ό μν κ°λ ₯νκ³ μ μ§ κ΄λ¦¬ κ°λ₯ν API ꡬμΆμ μν μ€μ©μ μΈ μμ μ λͺ¨λ² μ¬λ‘λ₯Ό μ 곡ν©λλ€.
Express.jsμμ νμ μμ μ±μ΄ μ€μν μ΄μ
JavaScriptμ κ°μ λμ μΈμ΄μμλ μ€λ₯κ° λ°νμμ λ°μνλ κ²½μ°κ° λ§μ μκΈ°μΉ μμ λμκ³Ό λλ²κ·ΈνκΈ° μ΄λ €μ΄ λ¬Έμ κ° λ°μν μ μμ΅λλ€. TypeScriptλ μ μ νμ΄νμ λμ νμ¬ μ΄λ₯Ό ν΄κ²°νλ―λ‘ κ°λ° μ€μ μ€λ₯κ° νλ‘λμ νκ²½μ λλ¬νκΈ° μ μ μ€λ₯λ₯Ό μ‘μ μ μμ΅λλ€. Express.jsμ λ§₯λ½μμ νμ μμ μ±μ μμ² λ° μλ΅ κ°μ²΄, 쿼리 λ§€κ°λ³μ λ° μμ² λ³Έλ¬Έμ μ²λ¦¬νλ λΌμ°νΈ νΈλ€λ¬μ νΉν μ€μν©λλ€. μ΄λ¬ν μμλ₯Ό μλͺ» μ²λ¦¬νλ©΄ μ ν리μΌμ΄μ μΆ©λ, λ°μ΄ν° μμ λ° λ³΄μ μ·¨μ½μ μ΄ λ°μν μ μμ΅λλ€.
- μ΄κΈ° μ€λ₯ κ°μ§: κ°λ° μ€μ νμ κ΄λ ¨ μ€λ₯λ₯Ό μ‘μ λ°νμμ μμμΉ λͺ»ν μν©μ΄ λ°μν κ°λ₯μ±μ μ€μ λλ€.
- ν₯μλ μ½λ μ μ§ κ΄λ¦¬μ±: νμ μ£Όμμ ν΅ν΄ μ½λλ₯Ό λ μ½κ² μ΄ν΄νκ³ λ¦¬ν©ν°λ§ν μ μμ΅λλ€.
- ν₯μλ μ½λ μμ± λ° λꡬ μ§μ: IDEλ νμ μ 보λ₯Ό ν΅ν΄ λ λμ μ μκ³Ό μ€λ₯ κ²μ¬λ₯Ό μ 곡ν μ μμ΅λλ€.
- λ²κ·Έ κ°μ: νμ μμ μ±μ ν¨μμ μλͺ»λ λ°μ΄ν° νμ μ μ λ¬νλ κ²κ³Ό κ°μ μΌλ°μ μΈ νλ‘κ·Έλλ° μ€λ₯λ₯Ό λ°©μ§νλ λ° λμμ΄ λ©λλ€.
TypeScript Express.js νλ‘μ νΈ μ€μ
λΌμ°νΈ νΈλ€λ¬ νμ μμ μ±μ λ€μ΄κ°κΈ° μ μ κΈ°λ³Έ TypeScript Express.js νλ‘μ νΈλ₯Ό μ€μ ν΄ λ³΄κ² μ΅λλ€. μ΄λ μ°λ¦¬ μμ μ κΈ°μ΄κ° λ κ²μ λλ€.
μ μ 쑰건
- Node.js λ° npm(Node Package Manager)μ΄ μ€μΉλμ΄ μμ΄μΌ ν©λλ€. 곡μ Node.js μΉμ¬μ΄νΈμμ λ€μ΄λ‘λν μ μμ΅λλ€. μ΅μ μ νΈνμ±μ μν΄ μ΅μ λ²μ μ μ¬μ©νμμμ€.
- Visual Studio Codeμ κ°μ΄ TypeScriptλ₯Ό μ μ§μνλ μ½λ νΈμ§κΈ°κ° νμν©λλ€.
νλ‘μ νΈ μ΄κΈ°ν
- μ νλ‘μ νΈ λλ ν 리 μμ±:
mkdir typescript-express-app && cd typescript-express-app - μ npm νλ‘μ νΈ μ΄κΈ°ν:
npm init -y - TypeScript λ° Express.js μ€μΉ:
npm install typescript express - Express.jsμ© TypeScript μ μΈ νμΌ μ€μΉ(νμ
μμ μ±μ μ€μ):
npm install @types/express @types/node - TypeScript μ΄κΈ°ν:
npx tsc --init(μ΄λ κ² νλ©΄ TypeScript μ»΄νμΌλ¬λ₯Ό ꡬμ±νλtsconfig.jsonνμΌμ΄ μμ±λ©λλ€.)
TypeScript ꡬμ±
tsconfig.json νμΌμ μ΄κ³ μ μ νκ² κ΅¬μ±ν©λλ€. λ€μμ μν ꡬμ±μ
λλ€.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
μ£Όλͺ©ν΄μΌ ν μ£Όμ ꡬμ±:
target: ECMAScript λμ λ²μ μ μ§μ ν©λλ€.es6κ° μ’μ μμμ μ λλ€.module: λͺ¨λ μ½λ μμ±μ μ§μ ν©λλ€.commonjsλ Node.jsμ λν μΌλ°μ μΈ μ νμ λλ€.outDir: μ»΄νμΌλ JavaScript νμΌμ μΆλ ₯ λλ ν 리λ₯Ό μ§μ ν©λλ€.rootDir: TypeScript μμ€ νμΌμ λ£¨νΈ λλ ν 리λ₯Ό μ§μ ν©λλ€.strict: ν₯μλ νμ μμ μ±μ μν΄ λͺ¨λ μ격ν νμ κ²μ¬ μ΅μ μ νμ±νν©λλ€. μ΄κ²μ μ κ·Ή κΆμ₯λ©λλ€.esModuleInterop: CommonJSμ ES λͺ¨λ κ°μ μνΈ μ΄μ©μ±μ νμ±νν©λλ€.
μ§μ μ μμ±
src λλ ν 리λ₯Ό λ§λ€κ³ index.ts νμΌμ μΆκ°ν©λλ€.
mkdir src
touch src/index.ts
κΈ°λ³Έ Express.js μλ² μ€μ μΌλ‘ src/index.tsλ₯Ό μ±μλλ€.
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
app.get('/', (req: Request, res: Response) => {
res.send('Hello, TypeScript Express!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
λΉλ μ€ν¬λ¦½νΈ μΆκ°
TypeScript μ½λλ₯Ό μ»΄νμΌνλ €λ©΄ package.json νμΌμ λΉλ μ€ν¬λ¦½νΈλ₯Ό μΆκ°ν©λλ€.
"scripts": {
"build": "tsc",
"start": "node dist/index.js",
"dev": "npm run build && npm run start"
}
μ΄μ npm run devλ₯Ό μ€ννμ¬ μλ²λ₯Ό λΉλνκ³ μμν μ μμ΅λλ€.
λΌμ°νΈ νΈλ€λ¬ νμ μμ μ±: μμ² λ° μλ΅ νμ μ μ
λΌμ°νΈ νΈλ€λ¬ νμ
μμ μ±μ ν΅μ¬μ Request λ° Response κ°μ²΄μ λν νμ
μ μ¬λ°λ₯΄κ² μ μνλ λ° μμ΅λλ€. Express.jsλ 쿼리 λ§€κ°λ³μ, μμ² λ³Έλ¬Έ λ° λΌμ°νΈ λ§€κ°λ³μμ νμ
μ μ§μ ν μ μλ μ΄λ¬ν κ°μ²΄μ λν μ λ€λ¦ νμ
μ μ 곡ν©λλ€.
κΈ°λ³Έ λΌμ°νΈ νΈλ€λ¬ νμ
μ΄λ¦μ 쿼리 λ§€κ°λ³μλ‘ μμνλ κ°λ¨ν λΌμ°νΈ νΈλ€λ¬λΆν° μμνκ² μ΅λλ€.
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
interface NameQuery {
name: string;
}
app.get('/hello', (req: Request, res: Response) => {
const name = req.query.name;
if (!name) {
return res.status(400).send('Name parameter is required.');
}
res.send(`Hello, ${name}!`);
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
Request<any, any, any, NameQuery>λ μμ² κ°μ²΄μ νμ μ μ μν©λλ€.- 첫 λ²μ§Έ
anyλ λΌμ°νΈ λ§€κ°λ³μ(μ:/users/:id)λ₯Ό λνλ λλ€. - λ λ²μ§Έ
anyλ μλ΅ λ³Έλ¬Έ νμ μ λνλ λλ€. - μΈ λ²μ§Έ
anyλ μμ² λ³Έλ¬Έ νμ μ λνλ λλ€. NameQueryλ 쿼리 λ§€κ°λ³μμ ꡬ쑰λ₯Ό μ μνλ μΈν°νμ΄μ€μ λλ€.
NameQuery μΈν°νμ΄μ€λ₯Ό μ μνλ©΄ TypeScriptλ μ΄μ req.query.name μμ±μ΄ μ‘΄μ¬νκ³ string νμ
μΈμ§ νμΈν μ μμ΅λλ€. μ‘΄μ¬νμ§ μλ μμ±μ μ‘μΈμ€νκ±°λ μλͺ»λ νμ
μ κ°μ ν λΉνλ €κ³ νλ©΄ TypeScriptμμ μ€λ₯λ₯Ό νμν©λλ€.
μμ² λ³Έλ¬Έ μ²λ¦¬
μμ² λ³Έλ¬Έμ μλ½νλ λΌμ°νΈ(μ: POST, PUT, PATCH)μ κ²½μ° μμ² λ³Έλ¬Έμ λν μΈν°νμ΄μ€λ₯Ό μ μνκ³ Request νμ
μμ μ¬μ©ν μ μμ΅λλ€.
import express, { Request, Response } from 'express';
import bodyParser from 'body-parser';
const app = express();
const port = 3000;
app.use(bodyParser.json()); // JSON μμ² λ³Έλ¬Έ νμ±μ μ€μ
interface CreateUserRequest {
firstName: string;
lastName: string;
email: string;
}
app.post('/users', (req: Request, res: Response) => {
const { firstName, lastName, email } = req.body;
// μμ² λ³Έλ¬Έ μ ν¨μ± κ²μ¬
if (!firstName || !lastName || !email) {
return res.status(400).send('Missing required fields.');
}
// μ¬μ©μ μμ± μ²λ¦¬(μ: λ°μ΄ν°λ² μ΄μ€μ μ μ₯)
console.log(`Creating user: ${firstName} ${lastName} (${email})`);
res.status(201).send('User created successfully.');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
CreateUserRequestλ μμλλ μμ² λ³Έλ¬Έμ ꡬ쑰λ₯Ό μ μν©λλ€.app.use(bodyParser.json())μ JSON μμ² λ³Έλ¬Έμ νμ±νλ λ° μ€μν©λλ€. μμΌλ©΄req.bodyκ° μ μλμ§ μμ΅λλ€.- μ΄μ
Requestνμ μRequest<any, any, CreateUserRequest>μ΄λ©°, μ΄λ μμ² λ³Έλ¬Έμ΄CreateUserRequestμΈν°νμ΄μ€λ₯Ό μ€μν΄μΌ ν¨μ λνλ λλ€.
TypeScriptλ μ΄μ req.body κ°μ²΄μ μμλλ μμ±(firstName, lastName λ° email)μ΄ ν¬ν¨λμ΄ μκ³ ν΄λΉ νμ
μ΄ μ¬λ°λ₯Έμ§ νμΈν©λλ€. μ΄λ μλͺ»λ μμ² λ³Έλ¬Έ λ°μ΄ν°λ‘ μΈν΄ λ°μνλ λ°νμ μ€λ₯μ μνμ ν¬κ² μ€μ
λλ€.
λΌμ°νΈ λ§€κ°λ³μ μ²λ¦¬
λ§€κ°λ³μκ° μλ λΌμ°νΈ(μ: /users/:id)μ κ²½μ° λΌμ°νΈ λ§€κ°λ³μμ λν μΈν°νμ΄μ€λ₯Ό μ μνκ³ Request νμ
μμ μ¬μ©ν μ μμ΅λλ€.
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
interface UserParams {
id: string;
}
interface User {
id: string;
firstName: string;
lastName: string;
email: string;
}
const users: User[] = [
{ id: '1', firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
{ id: '2', firstName: 'Jane', lastName: 'Smith', email: 'jane.smith@example.com' },
];
app.get('/users/:id', (req: Request, res: Response) => {
const userId = req.params.id;
const user = users.find(u => u.id === userId);
if (!user) {
return res.status(404).send('User not found.');
}
res.json(user);
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
UserParamsλ λΌμ°νΈ λ§€κ°λ³μμ ꡬ쑰λ₯Ό μ μνμ¬idλ§€κ°λ³μκ° λ¬Έμμ΄μ΄μ΄μΌ ν¨μ μ§μ ν©λλ€.- μ΄μ
Requestνμ μRequest<UserParams>μ΄λ©°, μ΄λreq.paramsκ°μ²΄κ°UserParamsμΈν°νμ΄μ€λ₯Ό μ€μν΄μΌ ν¨μ λνλ λλ€.
TypeScriptλ μ΄μ req.params.id μμ±μ΄ μ‘΄μ¬νκ³ string νμ
μΈμ§ νμΈν©λλ€. μ΄λ μ‘΄μ¬νμ§ μλ λΌμ°νΈ λ§€κ°λ³μμ μ‘μΈμ€νκ±°λ μλͺ»λ νμ
μΌλ‘ μ¬μ©νλ κ²½μ° λ°μνλ μ€λ₯λ₯Ό λ°©μ§νλ λ° λμμ΄ λ©λλ€.
μλ΅ νμ μ§μ
μμ² νμ μμ μ±μ μ§μ€νλ κ²μ΄ μ€μνμ§λ§ μλ΅ νμ μ μ μνλ©΄ μ½λ λͺ νμ±μ΄ ν₯μλκ³ λΆμΌμΉλ₯Ό λ°©μ§νλ λ° λμμ΄ λ©λλ€. μλ΅μμ λ€μ 보λ΄λ λ°μ΄ν°μ νμ μ μ μν μ μμ΅λλ€.
import express, { Request, Response } from 'express';
const app = express();
const port = 3000;
interface User {
id: string;
firstName: string;
lastName: string;
email: string;
}
const users: User[] = [
{ id: '1', firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
{ id: '2', firstName: 'Jane', lastName: 'Smith', email: 'jane.smith@example.com' },
];
app.get('/users', (req: Request, res: Response) => {
res.json(users);
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ¬κΈ°μ Response<User[]>λ μλ΅ λ³Έλ¬Έμ΄ User κ°μ²΄μ λ°°μ΄μ΄μ΄μΌ ν¨μ μ§μ ν©λλ€. μ΄λ κ² νλ©΄ API μλ΅μμ μ¬λ°λ₯Έ λ°μ΄ν° ꡬ쑰λ₯Ό μΌκ΄λκ² λ³΄λ΄λ λ° λμμ΄ λ©λλ€. User[] νμ
μ μ€μνμ§ μλ λ°μ΄ν°λ₯Ό 보λ΄λ €κ³ νλ©΄ TypeScriptμμ κ²½κ³ λ₯Ό νμν©λλ€.
λ―Έλ€μ¨μ΄ νμ μμ μ±
λ―Έλ€μ¨μ΄ ν¨μλ Express.js μ ν리μΌμ΄μ μμ κ΅μ°¨ μ λ¨ λ¬Έμ λ₯Ό μ²λ¦¬νλ λ° νμμ μ λλ€. λ―Έλ€μ¨μ΄μμ νμ μμ μ±μ 보μ₯νλ κ²μ λΌμ°νΈ νΈλ€λ¬μμμ λ§μ°¬κ°μ§λ‘ μ€μν©λλ€.
λ―Έλ€μ¨μ΄ ν¨μ νμ΄ν
TypeScriptμμ λ―Έλ€μ¨μ΄ ν¨μμ κΈ°λ³Έ ꡬ쑰λ λΌμ°νΈ νΈλ€λ¬μ ꡬ쑰μ μ μ¬ν©λλ€.
import express, { Request, Response, NextFunction } from 'express';
function authenticationMiddleware(req: Request, res: Response, next: NextFunction) {
// μΈμ¦ λ‘μ§
const isAuthenticated = true; // μ€μ μΈμ¦ νμΈμΌλ‘ λ체
if (isAuthenticated) {
next(); // λ€μ λ―Έλ€μ¨μ΄ λλ λΌμ°νΈ νΈλ€λ¬λ‘ μ§ν
} else {
res.status(401).send('Unauthorized');
}
}
const app = express();
const port = 3000;
app.use(authenticationMiddleware);
app.get('/', (req: Request, res: Response) => {
res.send('Hello, authenticated user!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
NextFunctionμ Express.jsμμ μ 곡νλ νμ μΌλ‘, 체μΈμ λ€μ λ―Έλ€μ¨μ΄ ν¨μλ₯Ό λνλ λλ€.- λ―Έλ€μ¨μ΄ ν¨μλ λΌμ°νΈ νΈλ€λ¬μ λμΌν
Requestλ°Responseκ°μ²΄λ₯Ό μ¬μ©ν©λλ€.
μμ² κ°μ²΄ 보κ°
κ²½μ°μ λ°λΌ λ―Έλ€μ¨μ΄μμ Request κ°μ²΄μ μ¬μ©μ μ μ μμ±μ μΆκ°ν μ μμ΅λλ€. μλ₯Ό λ€μ΄ μΈμ¦ λ―Έλ€μ¨μ΄λ μμ² κ°μ²΄μ user μμ±μ μΆκ°ν μ μμ΅λλ€. νμ
μμ ν λ°©μμΌλ‘ μ΄ μμ
μ μννλ €λ©΄ Request μΈν°νμ΄μ€λ₯Ό 보κ°ν΄μΌ ν©λλ€.
import express, { Request, Response, NextFunction } from 'express';
interface User {
id: string;
username: string;
email: string;
}
// Request μΈν°νμ΄μ€ 보κ°
declare global {
namespace Express {
interface Request {
user?: User;
}
}
}
function authenticationMiddleware(req: Request, res: Response, next: NextFunction) {
// μΈμ¦ λ‘μ§(μ€μ μΈμ¦ νμΈμΌλ‘ λ체)
const user: User = { id: '123', username: 'johndoe', email: 'john.doe@example.com' };
req.user = user; // μμ² κ°μ²΄μ μ¬μ©μ μΆκ°
next(); // λ€μ λ―Έλ€μ¨μ΄ λλ λΌμ°νΈ νΈλ€λ¬λ‘ μ§ν
}
const app = express();
const port = 3000;
app.use(authenticationMiddleware);
app.get('/', (req: Request, res: Response) => {
const username = req.user?.username || 'Guest';
res.send(`Hello, ${username}!`);
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
- μ μ μ μΈμ μ¬μ©νμ¬
Express.RequestμΈν°νμ΄μ€λ₯Ό 보κ°ν©λλ€. RequestμΈν°νμ΄μ€μ νμUserμ μ νμ userμμ±μ μΆκ°ν©λλ€.- μ΄μ TypeScriptμμ λΆλ§μ μ κΈ°νμ§ μκ³ λΌμ°νΈ νΈλ€λ¬μμ
req.userμμ±μ μ‘μΈμ€ν μ μμ΅λλ€.req.user?.usernameμ `?`λ μ¬μ©μκ° μΈμ¦λμ§ μμ κ²½μ°λ₯Ό μ²λ¦¬νμ¬ μ μ¬μ μΈ μ€λ₯λ₯Ό λ°©μ§νλ λ° μ€μν©λλ€.
TypeScript Express ν΅ν© λͺ¨λ² μ¬λ‘
Express.js μ ν리μΌμ΄μ μμ TypeScriptμ μ΄μ μ κ·Ήλννλ €λ©΄ λ€μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄μμμ€.
- μ격 λͺ¨λ νμ±ν:
tsconfig.jsonνμΌμμ"strict": trueμ΅μ μ μ¬μ©νμ¬ λͺ¨λ μ격ν νμ κ²μ¬ μ΅μ μ νμ±νν©λλ€. μ΄λ μ μ¬μ μΈ μ€λ₯λ₯Ό μ‘°κΈ°μ μ‘κ³ λ λμ μμ€μ νμ μμ μ±μ 보μ₯νλ λ° λμμ΄ λ©λλ€. - μΈν°νμ΄μ€ λ° νμ λ³μΉ μ¬μ©: μΈν°νμ΄μ€ λ° νμ λ³μΉμ μ μνμ¬ λ°μ΄ν° ꡬ쑰λ₯Ό λνλ λλ€. μ΄λ κ² νλ©΄ μ½λλ₯Ό λ μ½κ² μ½κ³ μ μ§ κ΄λ¦¬ν μ μμ΅λλ€.
- μ λ€λ¦ νμ μ¬μ©: μ λ€λ¦ νμ μ νμ©νμ¬ μ¬μ¬μ© κ°λ₯νκ³ νμ μμ ν μ»΄ν¬λνΈλ₯Ό λ§λλλ€.
- λ¨μ ν μ€νΈ μμ±: λ¨μ ν μ€νΈλ₯Ό μμ±νμ¬ μ½λμ μ νμ±μ νμΈνκ³ νμ μ£Όμμ΄ μ ννμ§ νμΈν©λλ€. ν μ€νΈλ μ½λ νμ§μ μ μ§νλ λ° λ§€μ° μ€μν©λλ€.
- λ¦°ν° λ° ν¬λ§·ν° μ¬μ©: λ¦°ν°(μ: ESLint)μ ν¬λ§·ν°(μ: Prettier)λ₯Ό μ¬μ©νμ¬ μΌκ΄λ μ½λ© μ€νμΌμ μ μ©νκ³ μ μ¬μ μΈ μ€λ₯λ₯Ό μ‘μ΅λλ€.
anyνμ νΌνκΈ°:anyνμ μ μ¬μ©μ μ΅μνν©λλ€.anyνμ μ νμ κ²μ¬λ₯Ό μ°ννκ³ TypeScriptλ₯Ό μ¬μ©νλ λͺ©μ μ 무ν¨νν©λλ€. μ λμ μΌλ‘ νμν κ²½μ°μλ§ μ¬μ©νκ³ κ°λ₯νλ©΄ λ ꡬ체μ μΈ νμ λλ μ λ€λ¦μ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€.- νλ‘μ νΈλ₯Ό λ Όλ¦¬μ μΌλ‘ ꡬμ±: κΈ°λ₯μ κΈ°λ°μΌλ‘ νλ‘μ νΈλ₯Ό λͺ¨λ λλ ν΄λλ‘ κ΅¬μ±ν©λλ€. μ΄λ κ² νλ©΄ μ ν리μΌμ΄μ μ μ μ§ κ΄λ¦¬μ±κ³Ό νμ₯μ±μ΄ ν₯μλ©λλ€.
- μ’ μμ± μ£Όμ μ¬μ©: μ’ μμ± μ£Όμ 컨ν μ΄λλ₯Ό μ¬μ©νμ¬ μ ν리μΌμ΄μ μ μ’ μμ±μ κ΄λ¦¬νλ κ²μ΄ μ’μ΅λλ€. μ΄λ κ² νλ©΄ μ½λλ₯Ό λ μ½κ² ν μ€νΈνκ³ μ μ§ κ΄λ¦¬ν μ μμ΅λλ€. InversifyJSμ κ°μ λΌμ΄λΈλ¬λ¦¬κ° λ리 μ¬μ©λ©λλ€.
Express.jsλ₯Ό μν κ³ κΈ TypeScript κ°λ
λ°μ½λ μ΄ν° μ¬μ©
λ°μ½λ μ΄ν°λ ν΄λμ€ λ° ν¨μμ λ©νλ°μ΄ν°λ₯Ό μΆκ°νλ κ°κ²°νκ³ ννλ ₯μ΄ νλΆν λ°©λ²μ μ 곡ν©λλ€. λ°μ½λ μ΄ν°λ₯Ό μ¬μ©νμ¬ Express.jsμμ λΌμ°νΈ λ±λ‘μ κ°μνν μ μμ΅λλ€.
λ¨Όμ compilerOptionsμ "experimentalDecorators": trueλ₯Ό μΆκ°νμ¬ tsconfig.json νμΌμμ μ€νμ λ°μ½λ μ΄ν°λ₯Ό νμ±νν΄μΌ ν©λλ€.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true
}
}
κ·Έλ° λ€μ μ¬μ©μ μ μ λ°μ½λ μ΄ν°λ₯Ό λ§λ€μ΄ λΌμ°νΈλ₯Ό λ±λ‘ν μ μμ΅λλ€.
import express, { Router, Request, Response } from 'express';
function route(method: string, path: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
if (!target.__router__) {
target.__router__ = Router();
}
target.__router__[method](path, descriptor.value);
};
}
class UserController {
@route('get', '/users')
getUsers(req: Request, res: Response) {
res.send('List of users');
}
@route('post', '/users')
createUser(req: Request, res: Response) {
res.status(201).send('User created');
}
public getRouter() {
return this.__router__;
}
}
const userController = new UserController();
const app = express();
const port = 3000;
app.use('/', userController.getRouter());
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
routeλ°μ½λ μ΄ν°λ HTTP λ©μλμ κ²½λ‘λ₯Ό μΈμλ‘ μ¬μ©ν©λλ€.- ν΄λμ€μ μ°κ²°λ λΌμ°ν°μμ λ°μ½λ μ΄νΈλ λ©μλλ₯Ό λΌμ°νΈ νΈλ€λ¬λ‘ λ±λ‘ν©λλ€.
- μ΄λ κ² νλ©΄ λΌμ°νΈ λ±λ‘μ΄ κ°μνλκ³ μ½λλ₯Ό λ μ½κ² μ½μ μ μμ΅λλ€.
μ¬μ©μ μ μ νμ κ°λ μ¬μ©
νμ κ°λλ νΉμ λ²μ λ΄μμ λ³μμ νμ μ μ’νλ ν¨μμ λλ€. μ¬μ©μ μ μ νμ κ°λλ₯Ό μ¬μ©νμ¬ μμ² λ³Έλ¬Έ λλ 쿼리 λ§€κ°λ³μμ μ ν¨μ±μ κ²μ¬ν μ μμ΅λλ€.
interface Product {
id: string;
name: string;
price: number;
}
function isProduct(obj: any): obj is Product {
return typeof obj === 'object' &&
obj !== null &&
typeof obj.id === 'string' &&
typeof obj.name === 'string' &&
typeof obj.price === 'number';
}
import express, { Request, Response } from 'express';
import bodyParser from 'body-parser';
const app = express();
const port = 3000;
app.use(bodyParser.json());
app.post('/products', (req: Request, res: Response) => {
if (!isProduct(req.body)) {
return res.status(400).send('Invalid product data');
}
const product: Product = req.body;
console.log(`Creating product: ${product.name}`);
res.status(201).send('Product created');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
μ΄ μμμ:
isProductν¨μλ κ°μ²΄κ°ProductμΈν°νμ΄μ€λ₯Ό μ€μνλμ§ νμΈνλ μ¬μ©μ μ μ νμ κ°λμ λλ€./productsλΌμ°νΈ νΈλ€λ¬ λ΄μμisProductν¨μλ₯Ό μ¬μ©νμ¬ μμ² λ³Έλ¬Έμ μ ν¨μ±μ κ²μ¬ν©λλ€.- μμ² λ³Έλ¬Έμ΄ μ ν¨ν μ νμΈ κ²½μ° TypeScriptλ
ifλΈλ‘ λ΄μμreq.bodyκ°Productνμ μμ μλλ€.
API μ€κ³ μ μ μ κ³ λ € μ¬ν μ²λ¦¬
μ μΈκ³ μ¬μ©μλ₯Ό μν APIλ₯Ό μ€κ³ν λλ μ κ·Όμ±, μ¬μ© νΈμμ± λ° λ¬Ένμ κ°μμ±μ 보μ₯νκΈ° μν΄ λͺ κ°μ§ μμλ₯Ό κ³ λ €ν΄μΌ ν©λλ€.
- μ§μν λ° κ΅μ ν(i18n λ° L10n):
- μ½ν
μΈ νμ:
Accept-Languageν€λλ₯Ό κΈ°λ°μΌλ‘ μ½ν μΈ νμμ ν΅ν΄ μ¬λ¬ μΈμ΄ λ° μ§μμ μ§μν©λλ€. - λ μ§ λ° μκ° νμ μ§μ : λ€μν μ§μμμ λͺ¨νΈμ±μ νΌνκΈ° μν΄ λ μ§ λ° μκ° νμμ ISO 8601 νμμ μ¬μ©ν©λλ€.
- μ«μ νμ μ§μ : μ¬μ©μμ λ‘μΌμΌμ λ°λΌ μ«μ νμ μ§μ (μ: μμ κ΅¬λΆ κΈ°νΈ λ° μ² λ¨μ κ΅¬λΆ κΈ°νΈ)μ μ²λ¦¬ν©λλ€.
- ν΅ν μ²λ¦¬: μ¬λ¬ ν΅νλ₯Ό μ§μνκ³ νμν κ²½μ° νμ¨ μ 보λ₯Ό μ 곡ν©λλ€.
- ν μ€νΈ λ°©ν₯: μλμ΄ λ° νλΈλ¦¬μ΄μ κ°μ μ€λ₯Έμͺ½μμ μΌμͺ½(RTL) μΈμ΄λ₯Ό μμ©ν©λλ€.
- μ½ν
μΈ νμ:
- μκ°λ:
- μλ² μΈ‘μμ λ μ§ λ° μκ°μ UTC(Coordinated Universal Time)λ‘ μ μ₯ν©λλ€.
- μ¬μ©μκ° μ νΈνλ μκ°λλ₯Ό μ§μ νκ³ ν΄λΌμ΄μΈνΈ μΈ‘μμ κ·Έμ λ°λΌ λ μ§ λ° μκ°μ λ³νν μ μλλ‘ ν©λλ€.
moment-timezoneκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νμ¬ μκ°λ λ³νμ μ²λ¦¬ν©λλ€.
- λ¬Έμ μΈμ½λ©:
- λ€μν μΈμ΄μ κ΄λ²μν λ¬Έμλ₯Ό μ§μνκΈ° μν΄ λͺ¨λ ν μ€νΈ λ°μ΄ν°μ UTF-8 μΈμ½λ©μ μ¬μ©ν©λλ€.
- λ°μ΄ν°λ² μ΄μ€ λ° κΈ°ν λ°μ΄ν° μ μ₯ μμ€ν μ΄ UTF-8μ μ¬μ©νλλ‘ κ΅¬μ±λμ΄ μλμ§ νμΈν©λλ€.
- μ κ·Όμ±:
- μ κ·Όμ± μ§μΉ¨(μ: WCAG)μ μ€μνμ¬ μ₯μ κ° μλ μ¬μ©μκ° APIμ μ‘μΈμ€ν μ μλλ‘ ν©λλ€.
- μ΄ν΄νκΈ° μ¬μ΄ λͺ ννκ³ μ€λͺ μ μΈ μ€λ₯ λ©μμ§λ₯Ό μ 곡ν©λλ€.
- API λ¬Έμμμ μλ―Έλ‘ μ HTML μμ λ° ARIA μμ±μ μ¬μ©ν©λλ€.
- λ¬Ένμ κ°μμ±:
- λͺ¨λ μ¬μ©μκ° μ΄ν΄νμ§ λͺ»ν μ μλ λ¬Ένμ μΌλ‘ ꡬ체μ μΈ μ°Έμ‘°, κ΄μ©κ΅¬ λλ μ λ¨Έλ₯Ό μ¬μ©νμ§ λ§μμμ€.
- μμ¬ μν΅ μ€νμΌκ³Ό μ νΈλμμ λ¬Ένμ μ°¨μ΄λ₯Ό μΌλμ λμμμ€.
- APIκ° λ€μν λ¬Έν κ·Έλ£Ήμ λ―ΈμΉλ μ μ¬μ μν₯μ κ³ λ €νκ³ κ³ μ κ΄λ μ΄λ νΈκ²¬μ μμννμ§ λ§μμμ€.
- λ°μ΄ν° κ°μΈ μ 보 λ³΄νΈ λ° λ³΄μ:
- GDPR(General Data Protection Regulation) λ° CCPA(California Consumer Privacy Act)μ κ°μ λ°μ΄ν° κ°μΈ μ 보 λ³΄νΈ κ·μ μ μ€μν©λλ€.
- μ¬μ©μ λ°μ΄ν°λ₯Ό 보νΈνκΈ° μν΄ κ°λ ₯ν μΈμ¦ λ° κΆν λΆμ¬ λ©μ»€λμ¦μ ꡬνν©λλ€.
- μ μ‘ μ€ λ° μ ν΄ μνμμ μ€μν λ°μ΄ν°λ₯Ό μνΈνν©λλ€.
- μ¬μ©μμκ² μμ μ λ°μ΄ν°μ λν μ μ΄ κΆνμ μ 곡νκ³ μμ μ λ°μ΄ν°μ μ‘μΈμ€, μμ λ° μμ ν μ μλλ‘ ν©λλ€.
- API λ¬Έμ:
- μ΄ν΄νκ³ νμνκΈ° μ¬μ΄ ν¬κ΄μ μ΄κ³ μ μ 리λ API λ¬Έμλ₯Ό μ 곡ν©λλ€.
- Swagger/OpenAPIμ κ°μ λꡬλ₯Ό μ¬μ©νμ¬ λνν API λ¬Έμλ₯Ό μμ±ν©λλ€.
- λ€μν μ²μ€μ μν΄ μ¬λ¬ νλ‘κ·Έλλ° μΈμ΄λ‘ μ½λ μμ λ₯Ό ν¬ν¨ν©λλ€.
- λ λμ μ²μ€μκ² λ€κ°κ°κΈ° μν΄ API λ¬Έμλ₯Ό μ¬λ¬ μΈμ΄λ‘ λ²μν©λλ€.
- μ€λ₯ μ²λ¦¬:
- ꡬ체μ μ΄κ³ μ μ©ν μ€λ₯ λ©μμ§λ₯Ό μ 곡ν©λλ€. "Something went wrong."κ³Ό κ°μ μΌλ°μ μΈ μ€λ₯ λ©μμ§λ₯Ό νΌνμμμ€.
- νμ€ HTTP μν μ½λλ₯Ό μ¬μ©νμ¬ μ€λ₯ μ νμ λνλ λλ€(μ: μλͺ»λ μμ²μ κ²½μ° 400, κΆνμ΄ μλ κ²½μ° 401, λ΄λΆ μλ² μ€λ₯μ κ²½μ° 500).
- λ¬Έμ λ₯Ό μΆμ νκ³ λλ²κ·Ένλ λ° μ¬μ©ν μ μλ μ€λ₯ μ½λ λλ μλ³μλ₯Ό ν¬ν¨ν©λλ€.
- λλ²κΉ λ° λͺ¨λν°λ§μ μν΄ μλ² μΈ‘μμ μ€λ₯λ₯Ό κΈ°λ‘ν©λλ€.
- μλ μ ν: APIλ₯Ό λ¨μ©μΌλ‘λΆν° 보νΈνκ³ κ³΅μ ν μ¬μ©μ 보μ₯νκΈ° μν΄ μλ μ νμ ꡬνν©λλ€.
- λ²μ κ΄λ¦¬: μ΄μ λ²μ κ³Ό νΈνλλ λ³κ²½μ νμ©νκ³ κΈ°μ‘΄ ν΄λΌμ΄μΈνΈμ μμμ λ°©μ§νκΈ° μν΄ API λ²μ κ΄λ¦¬λ₯Ό μ¬μ©ν©λλ€.
κ²°λ‘
TypeScript Express ν΅ν©μ λ°±μλ APIμ μμ μ±κ³Ό μ μ§ κ΄λ¦¬μ±μ ν¬κ² ν₯μμν΅λλ€. λΌμ°νΈ νΈλ€λ¬ λ° λ―Έλ€μ¨μ΄μμ νμ μμ μ±μ νμ©νμ¬ κ°λ° νλ‘μΈμ€ μ΄κΈ°μ μ€λ₯λ₯Ό μ‘κ³ μ μΈκ³ μ¬μ©μλ₯Ό μν λ³΄λ€ κ°λ ₯νκ³ νμ₯ κ°λ₯ν μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€. μμ² λ° μλ΅ νμ μ μ μνλ©΄ APIκ° μΌκ΄λ λ°μ΄ν° ꡬ쑰λ₯Ό μ€μνμ¬ λ°νμ μ€λ₯μ κ°λ₯μ±μ μ€μ λλ€. μ격 λͺ¨λ νμ±ν, μΈν°νμ΄μ€ λ° νμ λ³μΉ μ¬μ©, λ¨μ ν μ€νΈ μμ±κ³Ό κ°μ λͺ¨λ² μ¬λ‘λ₯Ό μ€μνμ¬ TypeScriptμ μ΄μ μ κ·Ήλννλ κ²μ μμ§ λ§μμμ€. APIκ° μ μΈκ³μ μΌλ‘ μ‘μΈμ€ κ°λ₯νκ³ μ¬μ© κ°λ₯νμ§ νμΈνλ €λ©΄ νμ μ§μν, μκ°λ λ° λ¬Ένμ κ°μμ±κ³Ό κ°μ μ μ μμλ₯Ό κ³ λ €νμμμ€.